Passed
Pull Request — development (#109)
by Karl
12:39
created

ZonesService.findByCity   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
dl 0
loc 7
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1 11
import { Injectable } from '@nestjs/common';
2 11
import { InjectRepository } from '@nestjs/typeorm';
3 11
import { Repository } from 'typeorm';
4 11
import { Zone } from './entities/zone';
5
import { ZoneQuery } from './types/ZoneQuery';
6
import { ZoneResponse } from './types/ZoneResponse';
7 11
import { BicyclesService } from 'src/bicycles/bicycles.service';
8 11
import { getDistance, positionInsidePolygon } from 'src/utils/geo.utils';
9
import { CityName } from 'src/cities/types/city.enum';
10
11
@Injectable()
12 11
export class ZonesService {
13
  constructor(
14
    @InjectRepository(Zone)
15 24
    private readonly zoneRepository: Repository<Zone>,
16 24
    private readonly bicyclesService: BicyclesService,
17
  ) {}
18
19
  async findAll(): Promise<Zone[]> {
20 37
    return await this.zoneRepository.find({
21
      relations: ['speedZone', 'city'],
22
    });
23
  }
24
25
  async findByCity(cityName: CityName): Promise<Zone[]> {
26 3
    return await this.zoneRepository.find({
27
      relations: ['city'],
28
      where: {
29
        city: {
30
          name: cityName,
31
        },
32
      },
33
    });
34
  }
35
36
  // seems unused
37
  // async getZones(lat: number, lon: number): Promise<Zone[]> {
38
  //   let zones = await this.findAll();
39
  //   zones = zones.filter((zone) => {
40
  //     return positionInsidePolygon(lat, lon, zone.polygon);
41
  //   });
42
  //   return zones;
43
  // }
44
45
  async getZonesByFilter(query: ZoneQuery): Promise<ZoneResponse> {
46 10
    const zones: ZoneResponse = {
47
      zones: [],
48
    };
49 10
    zones.zones = await this.findAll();
50
51 10
    if (query.city && query.city.length > 0) {
52 3
      zones.zones = zones.zones.filter((zone) => {
53 17
        return query.city.includes(zone.city.name);
54
      });
55
    }
56
57 10
    if (query.type && query.type.length > 0) {
58 3
      zones.zones = zones.zones.filter((zone) => {
59 16
        return query.type.includes(zone.type);
60
      });
61
    }
62
63 10
    if (query.lat && query.lon) {
64 2
      console.log(query.lat, query.lon);
65 2
      zones.zones = zones.zones.filter((zone) => {
66 14
        return (
67
          getDistance(query.lat, query.lon, zone.polygon[0].lat, zone.polygon[0].lng) <= query.rad
68
        );
69
      });
70
    }
71
72 10
    if (query.includes && query.includes.length > 0) {
73 3
      const allBikes = await this.bicyclesService.findAll();
74 3
      zones.zones = zones.zones.map((zone) => {
75 15
        const bikes = allBikes.filter((bike) => {
76 404
          return positionInsidePolygon(bike.latitude, bike.longitude, zone.polygon);
77
        });
78 15
        return {
79
          ...zone,
80
          bikes: bikes,
81
        };
82
      });
83
    }
84
85 10
    return zones;
86
  }
87
88
  async getZoneTypesForPosition(lat: number, lon: number): Promise<string[]> {
89 3
    const parkingZones = (await this.findAll()).filter((zone) => {
90 33
      return zone.type === 'parking';
91
    });
92 3
    const chargingZones = (await this.findAll()).filter((zone) => {
93 33
      return zone.type === 'charging';
94
    });
95
96 3
    const parking = parkingZones.some((zone) => {
97 15
      return positionInsidePolygon(lat, lon, zone.polygon);
98
    });
99
100 3
    const charging = chargingZones.some((zone) => {
101 9
      return positionInsidePolygon(lat, lon, zone.polygon);
102
    });
103
104 3
    const types = [];
105
106 3
    if (parking) {
107
      types.push('Parking');
108
    }
109
110 3
    if (charging) {
111
      types.push('Charging');
112
    }
113
114 3
    return types;
115
  }
116
117
  async pointInParkingZone(lat: number, lon: number): Promise<boolean> {
118 20
    const zones = (await this.findAll()).filter((zone) => {
119 204
      return zone.type === 'parking';
120
    });
121 20
    return zones.some((zone) => {
122 58
      return positionInsidePolygon(lat, lon, zone.polygon);
123
    });
124
  }
125
}
126